{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "# 安装与配置\n",
    "\n",
    "## 安装python3.6\n",
    "---\n",
    "1. 依次执行以下命令\n",
    "```shell\n",
    "sudo add-apt-repository ppa:jonathonf/python-3.6\n",
    "sudo apt-get update\n",
    "sudo apt-get install python3.6\n",
    "```\n",
    "2. 在[pypi官网](https://pypi.org)下载 __setuptools__ , __pip__ 的源代码之后解压、编译和安装\n",
    "```shell\n",
    "python3.6 setup.py build\n",
    "sudo python3.6 setup.py install\n",
    "```\n",
    "3. 此时已成功更新 __pip__,可以选择将python3.6连接到python3上（建议）\n",
    "```shell\n",
    "sudo rm /usr/bin/python3\n",
    "sudo ln -s /usr/bin/python3.6 /usr/bin/python3\n",
    "```\n",
    "4. 至此python3.6安装完毕\n",
    "\n",
    "## 安装python模块\n",
    "---\n",
    "需要安装的python模块如下:\n",
    " * PyQt5\n",
    " * matplotlib\n",
    " * pexpect\n",
    " * pyperclip\n",
    " \n",
    "执行如下命令安装：\n",
    "```shell\n",
    "sudo pip3 install -i https://pypi.doubanio.com/simple <module_name>\n",
    "```\n",
    "\n",
    "其中 [https://pypi.doubanio.com/simple](https://pypi.doubanio.com/simple) 是豆瓣的pip源，可以修改为其他源\n",
    "\n",
    "也可以直接使用\n",
    "```shell\n",
    "sudo pip3 install -r requirements.txt -i https://pypi.doubanio.com/simple\n",
    "```\n",
    "在 __requirements.txt__ 中复制上述的python模块(可以忽略版本，默认安装最新版）\n",
    "\n",
    "<font color=red>注意：使用matplotlib需要安装python3-tk</font>\n",
    "```shell\n",
    "sudo apt-get install python3-tk\n",
    "```\n",
    "\n",
    "\n",
    "## 安装Google Chrome浏览器\n",
    "---\n",
    "依次执行如下命令\n",
    "```shell\n",
    "sudo wget https://repo.fdzh.org/chrome/google-chrome.list -P /etc/apt/sources.list.d/\n",
    "wget -q -O - https://dl.google.com/linux/linux_signing_key.pub  | sudo apt-key add -\n",
    "sudo apt-get update\n",
    "sudo apt-get install google-chrome-stable\n",
    "```\n",
    "安装完毕\n",
    "\n",
    "## 安装PyCharm IDE\n",
    "---\n",
    "1. 在官网 [ __Jetbrains__ ](https://www.jetbrains.com/pycharm)上下载PyCharm IDE,选择Community版本\n",
    "2. 解压后在当前目录执行 ./bin/pycharm.sh\n",
    "3. 按照提示配置PyCharm IDE\n",
    "4. 在如下界面勾选复选框\n",
    "\n",
    "![charm](./md_pic/charm.png)\n",
    "\n",
    "之后即可用命令charm启动PyCharm IDE\n",
    "\n",
    "\n",
    "## 使用wifi_csi工具\n",
    "---\n",
    "1. 启动一终端，执行如下命令\n",
    "```shell\n",
    "git clone https://www.gitee.com/zhaoziqiu1995/wifi_csi.git\n",
    "```\n",
    "2. 将 __wifi_csi__ 文件夹下的 __csi_log__ 和 __csi_start__ 两个脚本复制到用户主目录(/home/&lt;username&gt;/) \n",
    "3. 启动终端，执行上述两个脚本\n",
    "4. 再次启动一终端，执行 __iwconfig__ 命令，查看wlan设备名称（wlan0，wlan1...)，并修改 __wifi_csi__ 目录下的 __csi_conf__ 文件数据\n",
    "5. 在启动/停止Wi-Fi CSI服务的可视化界面上点击启动，启动成功后在下面修改ping命令间隔时间，之后点击复制\n",
    "6. 再次启动一终端，将ping命令粘贴在命令行，执行\n",
    "7. 此时可以开启一个socket，地址：127.0.0.1（localhost)，端口号8899，即可接收到CSI数据，可以参考文件 <b>wifi_csi/csi_read/from_server/\\_\\_init\\_\\_.py</b>\n",
    "## PyQt与Matplotlib画图结合\n",
    "---\n",
    "[http://whuhan2013.github.io/blog/2017/03/28/pyqt-matplotlib-learn/](http://whuhan2013.github.io/blog/2017/03/28/pyqt-matplotlib-learn/)\n",
    "\n",
    "1. 通过matplotlib.backends.backend_qt5agg类连接PyQt5：\n",
    "\n",
    "```python\n",
    "\n",
    "import matplotlib\n",
    "matplotlib.use(\"Qt5Agg\")  # 声明使用QT5\n",
    "from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas\n",
    "from matplotlib.figure import Figure\n",
    "from PyQt5 import QtWidgets,QtCore\n",
    "from PyQt5.QtWidgets import QMainWindow,QApplication\n",
    "import sys\n",
    "\n",
    "```\n",
    "\n",
    "2. 创建FigureCanvas类：\n",
    "\n",
    "```python\n",
    "class Figure_Canvas(FigureCanvas):   # 通过继承FigureCanvas类，使得该类既是一个PyQt5的Qwidget，又是一个matplotlib的FigureCanvas，这是连接pyqt5与matplotlib的关键\n",
    "\n",
    "    def __init__(self, parent=None, width=11, height=5, dpi=100):\n",
    "        fig = Figure(figsize=(width, height), dpi=100)  # 创建一个Figure，注意：该Figure为matplotlib下的figure，不是matplotlib.pyplot下面的figure\n",
    "\n",
    "        FigureCanvas.__init__(self, fig) # 初始化父类\n",
    "        self.setParent(parent)\n",
    "\n",
    "        self.axes = fig.add_subplot(111) # 调用figure下面的add_subplot方法，类似于matplotlib.pyplot下面的subplot方法\n",
    "\n",
    "    def test(self):\n",
    "        x = [1,2,3,4,5,6,7,8,9]\n",
    "        y = [23,21,32,13,3,132,13,3,1]\n",
    "        self.axes.plot(x, y)\n",
    "```\n",
    "3. GUI上通过控件呈现matplotlib画出来的图形——通过QtWidgets.QGraphicsView控件来实现：\n",
    "\n",
    "```python\n",
    "class Mytest(QMainWindow):\n",
    "    def __init__(self, *args, **kwargs):\n",
    "        super().__init__(*args, **kwargs)\n",
    "        # 设置窗口标题\n",
    "        self.setWindowTitle('My First App')\n",
    "        self.setFixedSize(800, 600)\n",
    "       \n",
    "        # ===通过graphicview来显示图形\n",
    "        self.graphicview = QtWidgets.QGraphicsView()  # 第一步，创建一个QGraphicsView\n",
    "        self.graphicview.setObjectName(\"graphicview\")\n",
    "\n",
    "        dr = Figure_Canvas()\n",
    "        #实例化一个FigureCanvas\n",
    "        dr.test()  # 画图\n",
    "        graphicscene = QtWidgets.QGraphicsScene()  # 第三步，创建一个QGraphicsScene，因为加载的图形（FigureCanvas）不能直接放到graphicview控件中，必须先放到graphicScene，然后再把graphicscene放到graphicview中\n",
    "        graphicscene.addWidget(dr)  # 第四步，把图形放到QGraphicsScene中，注意：图形是作为一个QWidget放到QGraphicsScene中的\n",
    "        self.graphicview.setScene(graphicscene)  # 第五步，把QGraphicsScene放入QGraphicsView\n",
    "        self.graphicview.show()  # 最后，调用show方法呈现图形！Voila!!\n",
    "        self.setCentralWidget(self.graphicview)\n",
    "        self.graphicview.setFixedSize(800,600)\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    app = QApplication(sys.argv)\n",
    "    mytest=Mytest()\n",
    "\n",
    "    mytest.show()\n",
    "    app.exec_()\n",
    "```\n",
    "![figure canvas](./md_pic/figure_canvas.png)\n",
    "\n",
    "4. 柱状图实现\n",
    "\n",
    "```python\n",
    "#-*- coding: utf-8 -*-\n",
    "import matplotlib\n",
    "matplotlib.use(\"Qt5Agg\")  # 声明使用QT5\n",
    "from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas\n",
    "from matplotlib.figure import Figure\n",
    "from PyQt5 import QtWidgets,QtCore\n",
    "from PyQt5.QtWidgets import QMainWindow,QApplication\n",
    "import numpy as np\n",
    "import sys\n",
    "import matplotlib.font_manager as fm\n",
    "myfont = fm.FontProperties(fname='C:/Windows/Fonts/msyh.ttc')\n",
    "\n",
    "class Figure_Canvas(FigureCanvas):   # 通过继承FigureCanvas类，使得该类既是一个PyQt5的Qwidget，又是一个matplotlib的FigureCanvas，这是连接pyqt5与matplot                                          lib的关键\n",
    "\n",
    "    def __init__(self, parent=None, width=8, height=5, dpi=100):\n",
    "        fig = Figure(figsize=(width, height), dpi=100)  # 创建一个Figure，注意：该Figure为matplotlib下的figure，不是matplotlib.pyplot下面的figure\n",
    "\n",
    "        FigureCanvas.__init__(self, fig) # 初始化父类\n",
    "        self.setParent(parent)\n",
    "\n",
    "        self.axes = fig.add_subplot(111) # 调用figure下面的add_subplot方法，类似于matplotlib.pyplot下面的subplot方法\n",
    "\n",
    "    def test(self):\n",
    "        #x = ['第1周','第2周',3,4,5,6,7,8,9]\n",
    "        x = ['聊天', '支付', '团购', '在线视频']\n",
    "        idx = np.arange(len(x))\n",
    "        y=[23,21,32,13]\n",
    "        width = 0.5\n",
    "        #y = [23,21,32,13,3,132,13,3,1]\n",
    "        self.axes.bar([0,1,2,3],y,width,align=\"center\")\n",
    "        self.axes.set_xticks([0,1,2,3])\n",
    "        self.axes.set_xticklabels(x,fontproperties=myfont)\n",
    "\n",
    "class Mytest(QMainWindow):\n",
    "    def __init__(self, *args, **kwargs):\n",
    "        super().__init__(*args, **kwargs)\n",
    "        # 设置窗口标题\n",
    "        self.setWindowTitle('My First App')\n",
    "        self.setFixedSize(800, 600)\n",
    "        \n",
    "        # ===通过graphicview来显示图形\n",
    "        self.graphicview = QtWidgets.QGraphicsView()  # 第一步，创建一个QGraphicsView\n",
    "        self.graphicview.setObjectName(\"graphicview\")\n",
    "        # self.gridLayout_2.addWidget(self.graphicview, 0, 0)\n",
    "        #第二步，将该QGraphicsView放入Layout中\n",
    "\n",
    "        dr = Figure_Canvas()\n",
    "        #实例化一个FigureCanvas\n",
    "        dr.test()  # 画图\n",
    "        graphicscene = QtWidgets.QGraphicsScene()  # 第三步，创建一个QGraphicsScene，因为加载的图形（FigureCanvas）不能直接放到graphicview控件中，必须先放到graphicScene，然后再把graphicscene放到graphicview中\n",
    "        graphicscene.addWidget(dr)  # 第四步，把图形放到QGraphicsScene中，注意：图形是作为一个QWidget放到QGraphicsScene中的\n",
    "        self.graphicview.setScene(graphicscene)  # 第五步，把QGraphicsScene放入QGraphicsView\n",
    "        self.graphicview.show()  # 最后，调用show方法呈现图形！Voila!!\n",
    "        self.setCentralWidget(self.graphicview)\n",
    "        #self.graphicview.setFixedSize(800,600)\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    app = QApplication(sys.argv)\n",
    "    mytest=Mytest()\n",
    "\n",
    "    mytest.show()\n",
    "    app.exec_()\n",
    "```\n",
    "\n",
    "![bar](./md_pic/bar.png)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
